﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using TFSClient = Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Server;

using LeMigue.Scrum.Iterface.Service;
using LeMigue.Scrum.Iterface.Model;
using LeMigue.Framework.Utils;
using LeMigue.Scrum.Iterface.Enum;


namespace LeMigue.Scrum.TfsScrumV1.Service
{
    public class MemberService : AbstractTfsService, IMemberService
    {
        public IList<IMember> List(Team team)
        {
            IList<IMember> teammembros;

            teammembros = Cache.Get<IList<IMember>>(team.Id.ToString(),"Membros");

            if(teammembros != null)
                return teammembros;

            teammembros  = new List<IMember>();


            return List(TeamProjeto(team.Id));
        }

        private IList<IMember> List(TFSClient.Project teamproject)
        {
            IList<IMember> teammembros;

            teammembros = Cache.Get<IList<IMember>>(teamproject.Id.ToString(), "Membros");

            if (teammembros != null)
                return teammembros;

            teammembros = new List<IMember>();

            Identity[] grupos = ProjectGroups(teamproject);
            foreach (Identity grupo in grupos)
            {
                Group teamgrupo = new Group(grupo.DisplayName);

                Identity[] gruposMembers = GetMembros(teamproject, grupo.Sid);

                foreach (Identity membro in gruposMembers)
                {
                    teamgrupo.Add(membro.AccountName, new User(membro.DisplayName));
                }

                teammembros.Add(teamgrupo);
            }

            Cache.Set<IList<IMember>>(teamproject.Id.ToString(),"Membros", teammembros);

            return teammembros;
        }

        private Identity[] ProjectGroups(TFSClient.Project projeto)
        {
            return Sec.ListApplicationGroups(projeto.Uri.AbsoluteUri);
        }

        private Identity GetMembro(string memberSid)
        {
            return Sec.ReadIdentity(SearchFactor.Sid, memberSid, QueryMembership.None);
        }
        public Identity[] GetMembros(TFSClient.Project projeto, string groupSid)
        {
            IList<Identity> membros = new List<Identity>();
            Identity[] tmpmembers = Sec.ReadIdentities(SearchFactor.Sid, new string[] { groupSid }, QueryMembership.Expanded);
            foreach (Identity member in tmpmembers)
            {
                if (member.Members != null)
                {
                    foreach (string memberSid in member.Members)
                    {
                        Identity membroInfo = GetMembro(memberSid);
                        if (((membroInfo.Type == IdentityType.WindowsUser) && !membroInfo.Deleted))
                        {
                            membros.Add(membroInfo);
                        }
                    }
                }
            }
            return membros.ToArray();
        }


        internal IMember Load<T>(TFSClient.Project projeto, string nome) where T : IMember
        {
            return Find<T>(List(projeto), nome);
            
        }

        private IMember Find<T>(IList<IMember> teammembros, string nome) where T : IMember
        {
            IMember returnMembro = null;
            foreach (IMember mebro in teammembros)
            {
                if (mebro.Name == nome)
                {
                    returnMembro = mebro;
                    if (typeof(T) != returnMembro.GetType())
                        returnMembro = null;

                    break;
                }

                if (mebro.Tipo == MemberType.Group)
                {
                    returnMembro = Find<T>(((Group)mebro).Membros, nome);
                    if (returnMembro != null)
                        break;
                }
            }

            return returnMembro;
        }

    }
}
